package com.nononsenseapps.feeder.ui

import android.app.Application
import android.net.Uri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.nononsenseapps.feeder.db.entity.Feed
import com.nononsenseapps.feeder.model.opml.openOpml
import com.nononsenseapps.feeder.net.NetManager.Companion.defaultNetManager
import com.nononsenseapps.feeder.ui.base.CoroutineScopedViewModel
import com.nononsenseapps.feeder.util.getAppRootPath
import com.nononsenseapps.feeder.util.isTrue
import com.nononsenseapps.feeder.util.runTimes
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream

const val defaultOpmlFileName="navigationCache.opml"

class FeedNavigationViewModel (application: Application): CoroutineScopedViewModel(application) {

    private val defaultDownloadFile= getAppRootPath(application)!!.absolutePath+"/"+ defaultOpmlFileName

    val feedViewList= MutableLiveData<List<Feed>>()
    private var feedBase:List<Feed>?=null

    init {
        try {
            if (!isDefaultOpmlFileExits()) {
                val assentFile = application.assets.open("sample.opml")
                val fos =  FileOutputStream( File (defaultDownloadFile))
                val buffer = ByteArray(1024)
                var byteCount: Int
                do{
                    byteCount = assentFile.read(buffer)
                    if(byteCount==-1) break
                    fos.write(buffer, 0, byteCount)
                }while (true)
                fos.flush()
                assentFile.close()
                fos.close()
            }
            openWithLocal(Uri.fromFile(File(defaultDownloadFile)))
        }catch (e:Exception){
            Timber.d(" init faild.")
        }
    }

    fun syncFromNet(url:String){
        viewModelScope.launch(Dispatchers.IO) {
            defaultNetManager.download(url, getAppRootPath(getApplication())!!.absolutePath, defaultOpmlFileName,success = {
                Timber.d("sucess download opml file to :$it")
                openOpml(getApplication(), Uri.fromFile(File(it))).let {list->
                    feedBase = list
                    feedViewList.postValue(list)
                }
            },err = {
                Timber.d(" download opml faile:$it")
            })
        }
    }

    fun openWithLocal(uri:Uri){
        viewModelScope.launch {
            Timber.d(" open local opml file:$uri")
            openOpml(getApplication(), uri).let{
                feedBase = it
                feedViewList.postValue(it)
            }
        }
    }


    private fun isDefaultOpmlFileExits():Boolean=File(defaultDownloadFile).exists()

    fun feedHostFilter(filter:String){
        filter.isEmpty().isTrue {
            feedBase?.let {
                feedViewList.postValue(it)
            }
            return
        }
        feedBase?.let {feeds->
            feedViewList.postValue(feeds.filterNot { it.url.host.contains(filter,ignoreCase = true) })
        }
    }

    fun feedFilterWithNetConnectedCheck(timeOut:Long=200){
        feedViewList.value?.toMutableList()?.let {feeds->
            viewModelScope.launch {
                        feeds.filter { it.url.toString().isNotBlank() }.forEach {
                            viewModelScope.launch {
                                runTimes {
                                    Timber.d("filter url:${it.url}")
                                    if(!defaultNetManager.ping(it.url, timeOut)){
                                        feeds.remove(it)
                                        feedViewList.postValue(feeds)
                                    }
                                }
                            }
                        }
                }
        }
    }
}